package com.bingo.mpa.portal;

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;

import org.express.portal.ActionContext;
import org.express.portal.HttpUtils;
import org.express.portal.Mapping;
import org.express.portal.Utils;
import org.express.portal.persist.QueryHelper;
import org.express.portal.renderer.RedirectRenderer;
import org.express.portal.renderer.Renderer;
import org.express.portal.renderer.TemplateRenderer;
import org.express.portal.renderer.TextRenderer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.bingo.mpa.pojo.Pay;
import com.bingo.mpa.util.Common;
import com.bingo.mpa.util.Tools;

/**
 * 运营商管理员
 * @author Nixin
 * @version 1.1新加
 */
public class Manager
{
	private final Logger log = LoggerFactory.getLogger(getClass());
	
	@Mapping("/manager/order")
	public Renderer manager_order()
	{
		Map<String,Object> model = new HashMap<String,Object>();
		try
		{
			String token = HttpUtils.getCookie("mpa_token");
			String sql = "SELECT * FROM P_USER WHERE TOKEN=?";
			if(token == null)
			{
				return new RedirectRenderer("/login");
			}
			com.bingo.mpa.pojo.User user = QueryHelper.get(com.bingo.mpa.pojo.User.class,sql, new Object[]{token});
			if(user == null)
			{
				return new RedirectRenderer("/login");
			}
			byte role = user.getRole();
			switch(role)
			{
				case 1:
				case 2:
				case 3:
					return new RedirectRenderer("/login");
			}
			
			long aid = user.getAid();
			int status = HttpUtils.getIntParameter("status", -1);
			String dateType = HttpUtils.getStringParameter("dateType");
			String st = HttpUtils.getStringParameter("st");
			String et = HttpUtils.getStringParameter("et");
			if(dateType == null)
			{
				dateType = "today";
				st = Common.getMetaDate(dateType).getSt();
				et = Common.getMetaDate(dateType).getEt();
			}
			String keyword = HttpUtils.getStringParameter("keyword");
			keyword = Tools.replaceStr(keyword);
			StringBuffer sqll = new StringBuffer("SELECT COUNT(o.OID) FROM P_STORE s,P_ORDER o WHERE s.SID=o.SID");
			List<Object> ll = new ArrayList<Object>();
			if(aid > 0)
			{
				sqll.append(" AND o.AID="+aid);
			}
			if(status >0)
			{
				sqll.append(" AND o.STATUS="+status);
			}
			if(st != null && st.length() > 0)
			{
				sqll.append(" AND o.ORDER_TIME >=?");
				java.util.Date _st = org.apache.commons.lang.time.DateUtils.parseDate(st, new String[]{"yyyy-MM-dd"});
				ll.add(_st);
			}
			if(et != null && et.length() > 0)
			{
				sqll.append(" AND o.ORDER_TIME <?");
				java.util.Date _et = org.apache.commons.lang.time.DateUtils.parseDate(et, new String[]{"yyyy-MM-dd"});
				ll.add(_et);
			}
			if(keyword != null && keyword.length()>0)
			{
				sqll.append(" AND (o.PHONE LIKE '%"+keyword+"%')");
			}
			Object[] param = new Object[ll.size()];
			ll.toArray(param);
			long count = QueryHelper.stat(sqll.toString(), param);
			model.put("keyword", keyword);
			model.put("count", count);
			
			model.put("aid", aid);
			model.put("status", status);
			model.put("dateType", dateType);
			model.put("st", st);
			model.put("et", et);
		}
		catch(Exception e)
		{
			log.error("",e);
		}
		return new TemplateRenderer("/order_manager.html","model",model);
	}
	
	@Mapping("/manager/order/page")
	public Renderer order_page()
	{
		StringBuilder sb = new StringBuilder();
		try
		{
			int page = HttpUtils.getIntParameter("page",1);
			int pageSize = HttpUtils.getIntParameter("pageSize", 9);
			
			long aid = HttpUtils.getLongParameter("aid", -1);
			int status = HttpUtils.getIntParameter("status", -1);
			String st = HttpUtils.getStringParameter("st");
			String et = HttpUtils.getStringParameter("et");
			String keyword = HttpUtils.getStringParameter("keyword");
			keyword = Tools.replaceStr(keyword);
			List<Object> ll = new ArrayList<Object>();
			StringBuffer sql = new StringBuffer("SELECT s.NAME,o.* FROM P_STORE s,P_ORDER o WHERE s.SID=o.SID");
			if(aid > 0)
			{
				sql.append(" AND o.AID="+aid);
			}
			if(status >0)
			{
				sql.append(" AND o.STATUS="+status);
			}
			if(st != null && st.length() > 0)
			{
				sql.append(" AND o.ORDER_TIME >=?");
				java.util.Date _st = org.apache.commons.lang.time.DateUtils.parseDate(st, new String[]{"yyyy-MM-dd"});
				ll.add(_st);
			}
			if(et != null && et.length() > 0)
			{
				sql.append(" AND o.ORDER_TIME <?");
				java.util.Date _et = org.apache.commons.lang.time.DateUtils.parseDate(et, new String[]{"yyyy-MM-dd"});
				ll.add(_et);
			}
			if(keyword != null && keyword.length()>0)
			{
				sql.append(" AND (o.PHONE LIKE '%"+keyword+"%')");
			}
			sql.append(" ORDER BY o.OID DESC");
			Object[] param = new Object[ll.size()];
			ll.toArray(param);
			
			List<com.bingo.mpa.vo.OrderVO> objs = QueryHelper.query_slice(com.bingo.mpa.vo.OrderVO.class, sql.toString(), page, pageSize,param);
			
			sql = new StringBuffer("SELECT * FROM P_PACKAGE");
			List<com.bingo.mpa.pojo.Package> lp = QueryHelper.query_cache(com.bingo.mpa.pojo.Package.class, "packages", "packages", sql.toString(), new Object[]{});
			Map<Integer,com.bingo.mpa.pojo.Package> map = new HashMap<Integer,com.bingo.mpa.pojo.Package>();
			if(lp != null && lp.size() > 0)
			{
				for(com.bingo.mpa.pojo.Package obj : lp)
				{
					map.put(Integer.valueOf(obj.getPid()), obj);
				}
			}
			
			NumberFormat currentFormat=NumberFormat.getCurrencyInstance(Locale.CHINA);
			com.bingo.mpa.pojo.Package tmp = null;
			for(com.bingo.mpa.vo.OrderVO obj :objs)	
			{
				sb.append("<tr><td width=\"22\">");
				sb.append("<input type=\"checkbox\" id=\"order"+obj.getOid()+"\" name=\"orderid\" value=\""+obj.getOid()+"\"/>");
				sb.append("</td><td width=\"110\">");
				sb.append(org.apache.commons.lang.time.DateFormatUtils.format(obj.getOrder_time(), "yyyy/MM/dd HH:mm"));
				sb.append("</td><td width=\"120\">");
				sb.append(obj.getName());
				sb.append("</td><td width=\"30\">");
				sb.append(obj.getS_account());
				sb.append("</td><td class=\"num16\" width=\"100\">");
				sb.append(obj.getPhone().substring(0, 7));
				sb.append("<span class=\"orange\">"+obj.getPhone().substring(7)+"</span>");
				sb.append("</td><td width=\"110\">");
				tmp = map.get(obj.getPackage_());
				if(tmp != null)
				{
					switch(tmp.getCarrier())
					{
						case 1:
							sb.append("<img src=\"/images/icon_mobile.png\"/>");
							break;
						case 2:
							sb.append("<img src=\"/images/icon_unicom.png\"/>");
							break;
					}
					sb.append(tmp.getName());
				}
				sb.append("</td><td width=\"40\">");
				sb.append(currentFormat.format(obj.getRetail()/100.0));
				sb.append("</td><td width=\"40\">");
				sb.append(currentFormat.format(obj.getPrestore()/100.0));
				sb.append("</td><td width=\"40\">");
				sb.append(currentFormat.format(obj.getDiscount()/100.0));
				sb.append("</td><td width=\"40\">");
				sb.append(obj.getStatus()==1?"<span style=\"color:red\">待开卡</span>":obj.getStatus()==2?"<span style=\"color:green\">已开卡</span>":obj.getStatus()==3?"<span style=\"color:blue\">已撤单</span>":obj.getStatus()==4?"<span style=\"color:red\">已驳回</span>":"未知");
				sb.append("</td><td width=\"50\">");
				sb.append(obj.getPay_status()==1?"<span style=\"color:red\">未支付</span>":obj.getPay_status()==2?"<span style=\"color:blue\">处理中</span>":obj.getPay_status()==3?"<span style=\"color:green\">已支付</span>":obj.getPay_status()==4?"<span style=\"color:red\">失败</span>":"未知");
				sb.append("</td><td>");
				sb.append(obj.getRemark()==null?"":obj.getRemark());
				String prestore = "";
				if(obj.getPrestore()>0)
				{
					prestore = "（预存"+obj.getPrestore()/100+"）";
				}
				String pack = tmp != null?tmp.getName():"无";
				sb.append("</td><td width=\"70\" align=\"center\"><a href=\"#\" onclick=\"detail("+obj.getOid()+",'"+pack+prestore+"');\">");
				sb.append("详情</a>|");
				sb.append("<a href=\"#\" onclick=\"payOne("+obj.getOid()+");\">支付</a>");
				sb.append("</td></tr>");
			}
			if(objs.size()<9)
			{
				for(int i = 0;i<9-objs.size();i++)
				{
					sb.append("<tr><td>");
					sb.append("</td><td>");
					sb.append("</td><td>");
					sb.append("</td><td>");
					sb.append("</td><td>");
					sb.append("</td><td>");
					sb.append("</td><td>");
					sb.append("</td><td>");
					sb.append("</td><td>");
					sb.append("</td><td>");
					sb.append("</td><td>");
					sb.append("</td><td>");
					sb.append("</td><td>");
					sb.append("</td></tr>");
				}
			}
			log.info(page+","+pageSize);
		}
		catch(Exception e)
		{
			log.error("",e);
		}
		return new TextRenderer(sb.toString());
	}
	
	/**
	 * 支付，订单确认
	 * Ajax调用，弹出确认支付层
	 * @return
	 */
	@Mapping("/pay")
	public Renderer pay()
	{
		String ids = HttpUtils.getStringParameter("ids","");
		StringBuffer sql = new StringBuffer("SELECT * FROM P_ORDER WHERE STATUS = 2 AND PAY_STATUS<>3");
		List<com.bingo.mpa.pojo.Order> list = new ArrayList<com.bingo.mpa.pojo.Order>();
		try
		{
			if(ids != null && ids.length()>0)
			{
				sql.append(" AND OID IN ("+ids+")");
				list = QueryHelper.query(com.bingo.mpa.pojo.Order.class, sql.toString(), new Object[]{});
			}
			log.info(com.alibaba.fastjson.JSON.toJSONString(list));
		}
		catch(Exception e)
		{
			log.error("",e);
		}
		return new TextRenderer(com.alibaba.fastjson.JSON.toJSONString(list),"utf-8"); 
	}
	
	/**
	 * 提交订单
	 * @return
	 */
	@Mapping("/pay/post")
	public Renderer pay_post()
	{
		
		Map<String,Object> model = new HashMap<String,Object>();
		
		try
		{
			String token = HttpUtils.getCookie("mpa_token");
			String sql = "SELECT * FROM P_USER WHERE TOKEN=?";
			if(token == null)
			{
				return new RedirectRenderer("/login");
			}
			com.bingo.mpa.pojo.User user = QueryHelper.get(com.bingo.mpa.pojo.User.class,sql, new Object[]{token});
			if(user == null)
			{
				return new RedirectRenderer("/login");
			}
			byte role = user.getRole();
			switch(role)
			{
				case 1:
				case 2:
					return new RedirectRenderer("/login");
			}
			String ids = HttpUtils.getStringParameter("ids","");
			String bank_code = HttpUtils.getStringParameter("bank_code","");
			
			StringBuffer sqll = new StringBuffer("SELECT * FROM P_ORDER WHERE STATUS = 2 AND PAY_STATUS<>3");
			
			int total = 0;
			String product_desc = "";
			String product_name = "No.";
			if(ids != null && ids.length()>0)
			{
				sqll.append(" AND OID IN ("+ids+")");
				List<com.bingo.mpa.pojo.Order> list = QueryHelper.query(com.bingo.mpa.pojo.Order.class, sqll.toString(), new Object[]{});
				int i = 0;
				for(com.bingo.mpa.pojo.Order obj:list)
				{
					total += obj.getDiscount();
					total += obj.getPrestore();
					if(i > 0)
					{
						product_desc +=",";
					}
					product_desc += obj.getOid();
					if(i==0)
					{
						product_name += obj.getPhone();
					}
					i++;
				}
				if(list.size()>0)
				{
					product_name += "...";
				}
			}
			
			//load properties
			Properties pay_conf = new Properties();
			pay_conf.load(Manager.class.getResourceAsStream("/config/klksim.properties"));
			String merchant_code = pay_conf.getProperty("dinpay.merchant.code");
			String key = pay_conf.getProperty("dinpay.key");
			
			//参数
			model.put("bank_code", bank_code);
			String client_ip = ActionContext.getActionContext().getHttpServletRequest().getRemoteAddr();
			model.put("client_ip", client_ip);
			model.put("input_charset", "UTF-8");
			model.put("interface_version", "V3.0");
			model.put("key", key);
			model.put("merchant_code", merchant_code);
			model.put("notify_url", "https://www.klksim.com/dinpay/notify");
			model.put("product_desc", product_desc);
			model.put("product_name", product_name);
			model.put("service_type", "direct_pay");
			model.put("sign_type", "MD5");
			
			//签名
			StringBuffer sign_buf = new StringBuffer();
			sign_buf.append("bank_code=").append(bank_code);
			sign_buf.append("&client_ip=").append(client_ip);
			sign_buf.append("&input_charset=").append("UTF-8");
			sign_buf.append("&interface_version=").append("V3.0");
			sign_buf.append("&merchant_code=").append(merchant_code);
			sign_buf.append("&notify_url=").append("https://www.klksim.com/dinpay/notify");
			
			String order_amount = String.format("%.2f",total/100.0);
			sign_buf.append("&order_amount=").append(order_amount);
			model.put("order_amount", order_amount);
			
			String order_no = String.format("%1$tY%1$tm%1$td%1$tH%1$tM%1$tS%1$tL", new Date()) + Utils.getRandom(4);
			sign_buf.append("&order_no=").append(order_no);
			model.put("order_no", order_no);
			
			java.util.Calendar orderTime = java.util.Calendar.getInstance(Locale.CHINA);
			String order_time = org.apache.commons.lang.time.DateFormatUtils.format(orderTime.getTime(), "yyyy-MM-dd HH:mm:ss");
			sign_buf.append("&order_time=").append(order_time);
			model.put("order_time", order_time);
			
			sign_buf.append("&product_desc=").append(product_desc);
			sign_buf.append("&product_name=").append(product_name);
			sign_buf.append("&service_type=").append("direct_pay");
			//sign_buf.append("&sign_type=").append("MD5");
			sign_buf.append("&key=").append(key);
			
			log.info("post sign_buf="+sign_buf.toString());
			String sign = Utils.getMd5Sum(sign_buf.toString());
			log.info("sign = "+sign);
			model.put("sign", sign);
			
			//支付记录
			Pay pay = new Pay();
			pay.setPay_type((byte)1);//1:智付dinpay
			pay.setPay_id(order_no);
			pay.setS_account(user.getAccount());
			pay.setPay_time(new java.sql.Timestamp(orderTime.getTimeInMillis()));
			pay.setClient_ip(client_ip);
			pay.setProduct_name(product_name);
			pay.setProduct_desc(product_desc);
			pay.setAmount(total);
			pay.save();
			
			//更新订单支付状态
			if(product_desc.length()>0)
			{
				sql = "UPDATE P_ORDER SET PAY_STATUS = 2,PAY_ID=? WHERE STATUS=2 AND OID IN ("+product_desc+")";
				int batch = QueryHelper.update(sql, new Object[]{order_no});
				log.info(batch+"条订单记录提交支付，pay_id="+order_no);
			}
		}
		catch(Exception e)
		{
			log.error("",e);
		}
		return new TemplateRenderer("/pay_dinpay.html","model",model);
	}
	
	/**
	 * dinpay回调接口
	 * @return
	 */
	@Mapping("/dinpay/notify")
	public Renderer pay_dinpay_notify()
	{
		String ret = "SUCCESS";
		try
		{
			java.util.Calendar now = java.util.Calendar.getInstance(Locale.CHINA);
			String merchant_code = HttpUtils.getStringParameter("merchant_code");
			String notify_type = HttpUtils.getStringParameter("notify_type");
			String notify_id = HttpUtils.getStringParameter("notify_id");
			String interface_version = HttpUtils.getStringParameter("interface_version");
			String order_no = HttpUtils.getStringParameter("order_no");
			String order_time = HttpUtils.getStringParameter("order_time");
			String order_amount = HttpUtils.getStringParameter("order_amount","0.00");
			String trade_no = HttpUtils.getStringParameter("trade_no");
			String trade_time = HttpUtils.getStringParameter("trade_time");
			String trade_status = HttpUtils.getStringParameter("trade_status");
			String bank_code = HttpUtils.getStringParameter("bank_code");
			String bank_seq_no = HttpUtils.getStringParameter("bank_seq_no");
			String dinpaySign = HttpUtils.getStringParameter("sign");
			
			log.info("dinpay notify merchant_code="+merchant_code+",notify_type="+notify_type+",notify_id="+notify_id+
			         ",interface_version="+interface_version+",order_no="+order_no+",order_time="+order_time+
			         ",order_amount="+order_amount+",trade_no="+trade_no+",trade_time="+trade_time+
			         ",trade_status="+trade_status+",bank_code="+bank_code+",bank_seq_no="+bank_seq_no);
			//TODO:签名验证，先忽略
			StringBuffer sign_buf = new StringBuffer();
			if(bank_code != null && bank_code.length()>0)
			{
				sign_buf.append("bank_code").append(bank_code).append("&");
			}
			if(bank_seq_no != null && bank_seq_no.length()>0)
			{
				sign_buf.append("bank_seq_no=").append(bank_seq_no).append("&");
			}
			sign_buf.append("interface_version=").append(interface_version).append("&");
			sign_buf.append("merchant_code=").append(merchant_code).append("&");
			if(notify_id!=null && notify_id.length()>0)
			{
				sign_buf.append("notify_id=").append(notify_id).append("&");
			}
			sign_buf.append("notify_type=").append(notify_type).append("&");
			sign_buf.append("order_amount=").append(order_amount).append("&");
			sign_buf.append("order_no=").append(order_no).append("&");
			sign_buf.append("order_time=").append(order_time).append("&");
			sign_buf.append("trade_no=").append(trade_no).append("&");
			sign_buf.append("trade_status=").append(trade_status).append("&");
			if(trade_time !=null && trade_time.length()>0) {
				sign_buf.append("trade_time=").append(trade_time).append("&");
			}
			
			//load properties
			Properties pay_conf = new Properties();
			pay_conf.load(Manager.class.getResourceAsStream("/config/klksim.properties"));
			String key = pay_conf.getProperty("dinpay.key");
			
			sign_buf.append("key=").append(key);
			
			log.info("sign_buf="+sign_buf.toString());
			String sign = Utils.getMd5Sum(sign_buf.toString());
			log.info("gener sign="+sign);
			log.info("dinpaySign="+dinpaySign);
			
			if(order_no == null || order_no.length() !=21)
			{
				return new TextRenderer("FAILED,order_no length is illegal.","utf-8"); 
			}
			if(trade_time ==null || trade_time.length() != 19)
			{
				return new TextRenderer("ILLEGAL_ORDER_TIME_FORMAT","utf-8"); 
			}
			Date _trade_time = org.apache.commons.lang.time.DateUtils.parseDate(trade_time, new String[]{"yyyy-MM-dd HH:mm:ss"});
			
			//检查支付金额是否正确
			int p_amount = 0;
			if(order_amount != null && order_amount.length()>0)
			{
				Double pay_amount = Double.parseDouble(order_amount);
				pay_amount *=100;
				p_amount = pay_amount.intValue();
			}
			
			//支付状态
			int rsp_result = 2;
			if(trade_status!=null && trade_status.equals("SUCCESS"))
			{
				rsp_result = 1;
			}
				
			String sql = "UPDATE P_PAY SET RSP_TIME=?,NOTIFY_ID=?,TRADE_NO=?,TRADE_TIME=?,BANK_CODE=?,BANK_SEQ_NO=?,PAY_AMOUNT=?,RSP_RESULT=?,RSP_REMARK=? WHERE PAY_ID=?";
			QueryHelper.update(sql, new Object[]{new java.sql.Timestamp(now.getTimeInMillis()),notify_id,trade_no,new java.sql.Timestamp(_trade_time.getTime()),bank_code,bank_seq_no,p_amount,rsp_result,trade_status,order_no});
			log.info("update p_pay order_no == "+order_no);
			//如果支付成功，更新订单状态
			if(rsp_result==1)
			{
				sql = "UPDATE P_ORDER SET PAY_STATUS = 3 WHERE PAY_ID=?";
				int count = QueryHelper.update(sql, new Object[]{order_no});
				log.info("pay success and update pay_status to 3 for pay_id =="+order_no+",and "+count+",count record effected");
			}
		}
		catch(Exception e)
		{
			log.error("",e);
			ret = "FAILED";
		}
		return new TextRenderer(ret,"utf-8"); 
	}
}
